﻿using DocumentFormat.OpenXml.Packaging;
using DocumentFormat.OpenXml.Spreadsheet;
using DocumentFormat.OpenXml.Wordprocessing;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Data;

namespace KeyWordSearcher
{
    public class Tools
    {
        public static List<string> Getfiles(string filepath, string pattern, bool? childFolder)
        {
            string p = pattern;

            List<string> f_name_list = new List<string>();

            f_name_list = System.IO.Directory
                .GetFiles(filepath, p, System.IO.SearchOption.TopDirectoryOnly)
                .ToList<string>();

            if(childFolder == true)
            {
                DirectoryInfo directoryInfo = new DirectoryInfo(filepath);

                directoryInfo.Refresh();

                foreach(System.IO.DirectoryInfo item in directoryInfo.EnumerateDirectories())
                {
                    try
                    {
                        if((item.Attributes & FileAttributes.System) == System.IO.FileAttributes.System ||
                            (item.Attributes & FileAttributes.Hidden) == System.IO.FileAttributes.Hidden)
                        {
                        } else
                        {
                            //MessageBox.Show(item.FullName + item.Attributes.ToString());

                            foreach(var fileInfo in item.GetFiles("*", System.IO.SearchOption.AllDirectories))
                            {
                                f_name_list.Add(fileInfo.FullName);
                            }
                        }
                    } catch(Exception)
                    {
                        //throw;
                        continue;
                    }
                }
            }

            return f_name_list;
        }

        public static bool SearchKeywordInTxt(string filePath, string keyword, out List<string> outLines)
        {
            outLines = new List<string>();

            var keywordGroups = keyword.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(word => word.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
                .ToArray();

            try
            {
                using(var reader = new StreamReader(filePath))
                {
                    int lineNumber = 0;

                    string line;

                    while((line = reader.ReadLine()) != null)
                    {
                        lineNumber++;
                        bool isMatch = keywordGroups.All(
                            group => group.Any(
                                subWord => line.IndexOf(subWord, StringComparison.OrdinalIgnoreCase) >= 0));

                        if(isMatch)
                            outLines.Add($"Line {lineNumber}: {line.Trim()}");
                    }
                    return outLines.Count > 0;
                }
            } catch(IOException ex)
            {
                Console.WriteLine($"文件访问错误: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 实际采用代码，用于在xlsx文件中检索cell中字符串是否包含给定的字符串。
        /// </summary>
        /// <param name="filePath">xlsx文件的文件路径</param>
        /// <param name="keyword">要检索的关键字字符串</param>
        /// <param name="exactMatch">是否严格匹配（仅相等时判定为包含）</param>
        /// <param name="ignoreCase">是否忽略大小写</param>
        /// <returns></returns>
        public static List<string> SearchKeywordInXlsx(
            string filePath,
            string keyword,
            bool exactMatch = false,
            bool ignoreCase = true)
        {
            var results = new List<string>();

            var regexOptions = ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None;

            var keywordGroups = keyword.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(word => word.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
                .ToArray();

            try
            {
                using(SpreadsheetDocument doc = SpreadsheetDocument.Open(filePath, false))
                {
                    WorkbookPart workbookPart = doc.WorkbookPart;

                    SharedStringTablePart sharedStringPart = workbookPart.SharedStringTablePart;

                    foreach(Sheet sheet in workbookPart.Workbook.Sheets)
                    {
                        WorksheetPart worksheetPart = (WorksheetPart)workbookPart.GetPartById(sheet.Id);

                        DocumentFormat.OpenXml.OpenXmlReader reader = DocumentFormat.OpenXml.OpenXmlReader
                            .Create(worksheetPart);
                        while(reader.Read())
                        {
                            if(reader.ElementType == typeof(Row))
                            {
                                // 进入行元素内部
                                reader.ReadFirstChild(); // 移动到第一个子元素（如 Cell）
                                do
                                {
                                    if(reader.ElementType == typeof(Cell))
                                    {
                                        Cell cell = (Cell)reader.LoadCurrentElement();
                                        // 处理单元格逻辑...
                                        string cellValue = GetCellValue(doc, cell);
                                        if(string.IsNullOrEmpty(cellValue))
                                            continue;

                                        // 多条件联合匹配
                                        bool isMatch = keywordGroups.All(
                                            group => group.Any(
                                                pattern => Regex.IsMatch(cellValue, pattern, regexOptions)));

                                        if(isMatch)
                                        {
                                            results.Add($"工作表 '{sheet.Name}' 的 {cell.CellReference.Value}: {cellValue}");
                                        }
                                    }
                                } while (reader.ReadNextSibling()); // 遍历同级元素
                            }
                        }
                    }
                }


                return results;
            } catch(Exception ex)
            {
                return new List<string> { $"错误: {ex.Message}" };
            }
        }

        private static string GetCellValue(SpreadsheetDocument doc, Cell cell)
        {
            SharedStringTablePart stringTablePart = doc.WorkbookPart.SharedStringTablePart;

            string value = cell.InnerText;

            // 处理共享字符串类型
            if(cell.DataType != null && cell.DataType.Value == CellValues.SharedString)
            {
                int index = int.Parse(value);
                value = stringTablePart.SharedStringTable.Elements<SharedStringItem>().ElementAt(index).InnerText;
            }
 // 处理其他类型（数字、布尔值等）
 else if(cell.CellValue != null)
            {
                value = cell.CellValue.Text;
            }

            return value;
        }

        public static List<string> SearchKeywordInDocx(
            string filePath,
            string keyword,
            bool exactMatch = false,
            bool ignoreCase = true)
        {
            var results = new List<string>();

            var regexOptions = ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None;

            var keywordGroups = keyword.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(word => word.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
                .ToArray();

            try
            {
                using(WordprocessingDocument doc = WordprocessingDocument.Open(filePath, false))
                {
                    // 获取文档主体部分
                    Body body = doc.MainDocumentPart.Document.Body;

                    // 遍历所有段落
                    foreach(Paragraph paragraph in body.Elements<Paragraph>())
                    {
                        string paragraphText = "";

                        //paragraphText = GetParagraphText(paragraph);

                        paragraphText = paragraph.InnerText;

                        if(string.IsNullOrEmpty(paragraphText))
                            continue;

                        // 多条件联合匹配
                        bool isMatch = keywordGroups.All(
                            group => group.Any(pattern => Regex.IsMatch(paragraphText, pattern, regexOptions)));

                        if(isMatch)
                        {
                            results.Add(paragraphText);
                        }
                    }
                }


                return results;
            } catch(Exception ex)
            {
                return new List<string> { $"错误: {ex.Message}" };
            }
        }

        public static List<string> SearchKeywordInPptx(
            string filePath,
            string keyword,
            bool exactMatch = false,
            bool ignoreCase = true)
        {
            var results = new List<string>();

            var regexOptions = ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None;

            var keywordGroups = keyword.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                .Select(word => word.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
                .ToArray();

            try
            {
                using(PresentationDocument ppt = PresentationDocument.Open(filePath, false))
                {
                    var presentationPart = ppt.PresentationPart;

                    var slideIdList = presentationPart.Presentation.SlideIdList;

                    foreach(DocumentFormat.OpenXml.Presentation.SlideId slideId in slideIdList.ChildElements
                        .OfType<DocumentFormat.OpenXml.Presentation.SlideId>())
                    {
                        string relationshipId = slideId.RelationshipId;
                        SlidePart slidePart = (SlidePart)presentationPart.GetPartById(relationshipId);
                        DocumentFormat.OpenXml.Presentation.Slide slide = slidePart.Slide;

                        #region 利用Linq 实现

                        //var slideText = string.Join(
                        //    "\n",
                        //    slide.Descendants<DocumentFormat.OpenXml.Presentation.Shape>()
                        //        .Where(shape => shape.TextBody != null)  // 过滤非文本框形状
                        //        .SelectMany(
                        //            shape => shape.TextBody
                        //                    .Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>()
                        //                    .Select(
                        //                        paragraph => string.Join(
                        //                                    " ",
                        //                                    paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Run>()
                        //                                        .Where(run => run.Text != null)
                        //                                        .Where(
                        //                                            run => !string.IsNullOrWhiteSpace(
                        //                                                                run.Text.Text.Trim()))
                        //                                        .Select(run => run.Text.Text)))));

                        //if(string.IsNullOrEmpty(slideText))
                        //    continue;

                        #endregion

                        #region 用For循环实现相关功能

                        var slideTextBuilder = new StringBuilder();

                        var paragraphSeparator = "\n"; // 段落分隔符

                        // 第一层循环：遍历所有形状(Shape)
                        foreach (var shape in slide.Descendants<DocumentFormat.OpenXml.Presentation.Shape>())
                        {
                            // 过滤非文本框形状（检查TextBody是否存在）
                            if (shape.TextBody == null) continue;

                            // 第二层循环：遍历形状内的所有段落(Paragraph)
                            foreach (var paragraph in shape.TextBody.Descendants<DocumentFormat.OpenXml.Drawing.Paragraph>())
                            {
                                var runTexts = new List<string>();

                                // 第三层循环：遍历段落内的所有文本运行(Run)
                                foreach (var run in paragraph.Descendants<DocumentFormat.OpenXml.Drawing.Run>())
                                {
                                    // 过滤空文本运行
                                    if (run?.Text?.Text == null) continue;

                                    var trimmedText = run.Text.Text.Trim();
                                    // 过滤空白文本
                                    if (!string.IsNullOrWhiteSpace(trimmedText))
                                    {
                                        runTexts.Add(trimmedText);
                                    }
                                }

                                // 合并当前段落的所有有效文本（用空格连接）
                                if (runTexts.Count > 0)
                                {
                                    var paragraphText = string.Join(" ", runTexts);
                                    slideTextBuilder.Append(paragraphText);
                                }

                                // 添加段落分隔符（无论当前段落是否有内容）
                                slideTextBuilder.Append(paragraphSeparator);
                            }
                        }

                        var slideText = slideTextBuilder.ToString().TrimEnd('\n'); // 移除最后一个多余换行

                        #endregion


                        //System.Windows.MessageBox.Show(slideText);

                        // 多条件联合匹配
                        bool isMatch = keywordGroups.All(
                            group => group.Any(pattern => Regex.IsMatch(slideText, pattern, regexOptions)));

                        if(isMatch)
                        {
                            results.Add(slideText);
                        }
                    }
                }


                return results;
            } catch(Exception ex)
            {
                return new List<string> { $"错误: {ex.Message}" };
            }
        }


        //隐藏的方法1 txt
        /*
        public static string GetParagraphText(Paragraph paragraph)
        {
            //string paragraphText = "";

            //// 遍历段落内的 Run 元素
            //foreach (Run run in paragraph.Elements<Run>())
            //{
            //    // 提取所有 Text 元素并拼接
            //    foreach (Text text in run.Elements<Text>())
            //    {
            //        if (string.IsNullOrEmpty(text.Text)) continue;

            //        paragraphText += text.Text;
            //    }
            //}
            //return paragraphText;

            return paragraph.InnerText;

        }
        public static bool SearchKeywordInTxtV1(string filePath, string keyword, out List<string> outLines)
        {
            outLines = new List<string>();

            string[] tagS = keyword.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);


            // 打开文件流
            using (StreamReader reader = new StreamReader(filePath))
            {
                string line;
                int lineNumber = 0;

                // 逐行读取文件
                while ((line = reader.ReadLine()) != null)
                {
                    lineNumber++;

                    // 检查当前行是否包含关键字
                    //兼容大小写搜索  原来的代码
                    //if (line.ToLower().Contains(keyword.ToLower()))
                    //{
                    //    outLines.Add(line);

                    //}

                    bool allWordsFound = true;

                    foreach (string word in tagS)
                    {
                        //判断是否是可以包容的词

                        string[] tagSTmp = word.Split(new char[] { '|' }, StringSplitOptions.RemoveEmptyEntries);

                        //包含可选字符情况

                        if (tagSTmp.Length > 0)
                        {
                            bool tmp = false;

                            foreach (var item in tagSTmp)
                            {

                                if (line.ToLower().Contains(item.ToLower()))
                                {
                                    tmp = true; // 如果发现某个单词在字符串中，标记为找到 

                                    break; // 跳出循环，因为已经知道不是所有单词都找到了
                                }

                            }

                            if (!tmp)
                            {
                                allWordsFound = false;
                                break;
                            }
                        }
                        else
                        {
                            if (!line.ToLower().Contains(word.ToLower()))
                            {
                                allWordsFound = false; // 如果发现某个单词不在字符串中，标记为未找到
                                                       //Console.WriteLine($"The word '{word}' was not found in the string.");
                                break; // 跳出循环，因为已经知道不是所有单词都找到了
                            }

                        }

                    }

                    if (allWordsFound)
                    {
                        outLines.Add(line);

                    }

                }
            }

            if (outLines.Count > 0)
            {
                return true;
            }
            else
            {
                return false;

            }

        }
        */


        //隐藏的无效方法
        /*
         * 
        /// <summary>
        /// 简易版，不在正式代码中使用。
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="keyword"></param>
        /// <param name="exactMatch"></param>
        /// <param name="ignoreCase"></param>
        /// <returns></returns>
        public static List<string> SearchKeywordInXlsxV2(string filePath, string keyword, bool exactMatch = false, bool ignoreCase = true)
        {

            var results = new List<string>();

            using (var workbook = new Excel.XLWorkbook(filePath))
            {
                foreach (var worksheet in workbook.Worksheets)
                {
                    foreach (var cell in worksheet.CellsUsed())
                    {
                        string cellValue = cell.Value.ToString();
                        StringComparison comparison = ignoreCase ?
                            StringComparison.OrdinalIgnoreCase :
                            StringComparison.Ordinal;

                        bool isMatch = exactMatch ?
                            cellValue.Equals(keyword, comparison) :
                            cellValue.IndexOf(keyword, comparison) >= 0;

                        if (isMatch)
                        {
                            results.Add($"工作表 '{worksheet.Name}' 的 {cell.Address}: {cellValue}");
                        }
                    }
                }
            }
            return results;
        }
       */


        //隐藏的无效方法
        /*
        public static List<string> SearchKeywordInXlsxV3(string filePath, string keyword, bool exactMatch = false, bool ignoreCase = true)
        {
            var results = new List<string>();

            var regexOptions = ignoreCase ? RegexOptions.IgnoreCase : RegexOptions.None;

            var keywordGroups = keyword.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)
                                .Select(word => word.Split(new[] { '|' }, StringSplitOptions.RemoveEmptyEntries))
                                .ToArray();

            try
            {
                using (var workbook = new Excel.XLWorkbook(filePath))
                {
                    foreach (var worksheet in workbook.Worksheets)
                    {
                        var firstRow = worksheet.FirstRowUsed();
                        var lastRow = worksheet.LastRowUsed();
                        if (firstRow == null || lastRow == null) continue;

                        foreach (var row in worksheet.Rows(firstRow.RowNumber(), lastRow.RowNumber()))
                        {
                            foreach (var cell in row.CellsUsed())
                            {
                                string cellValue = cell.GetString();
                                if (string.IsNullOrEmpty(cellValue)) continue;

                                // 多条件联合匹配
                                bool isMatch = keywordGroups.All(group =>
                                    group.Any(pattern =>
                                        Regex.IsMatch(cellValue, pattern, regexOptions)));

                                if (isMatch)
                                {
                                    results.Add($"工作表 '{worksheet.Name}' 的 {cell.Address}: {cellValue}");
                                }
                            }
                        }
                    }
                }
                return results;
            }
            catch (Exception ex)
            {
                return new List<string> { $"错误: {ex.Message}" };
            }
        }
        */
    }


    public class SelectIdexConvert : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int selectIndex = (int)value;


            if(selectIndex == 1 || selectIndex == 2 || selectIndex == 3 || selectIndex == 4)
            {
                return "Visible";
            } else
            {
                return "Collapsed";
            }

            throw new NotImplementedException();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        { throw new NotImplementedException(); }
    }

    public class ItemsCountConvert : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            int itemsCount = (int)value;


            if(itemsCount > 0)
            {
                return "Visible";
            } else
            {
                return "Collapsed";
            }

            throw new NotImplementedException();
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        { throw new NotImplementedException(); }
    }
}
